package ui;

import gov.nasa.worldwind.BasicModel;
import gov.nasa.worldwind.Configuration;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.AnnotationLayer;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.layers.Earth.MSVirtualEarthLayer;
import gov.nasa.worldwind.layers.Mercator.examples.VirtualEarthLayer;
import gov.nasa.worldwind.render.GlobeAnnotation;
import gov.nasa.worldwind.render.Material;
import gov.nasa.worldwind.render.Polyline;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

import bean.RuteBean;
import cas.CAS;
import cas.Identity;
import dao.DAOFactory;
import dao.ResourceManager;
import dao.oracle.RuteDao;

public class MainFrame extends JFrame implements Observer{
	private static MainFrame thisFrame;
	private CAS cas;
	private List<SurfaceObject> listObject;
	private WorldWindowGLCanvas wwd;
	private Thread displayThread;
	private AnnotationLayer annotLayer;
	private EastPanel eastPanel;
	private SouthPanel southPanel;
	ObjectDisplayer objectDisplayer;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Configuration.setValue(AVKey.INITIAL_LATITUDE, -6.9495486);
					Configuration.setValue(AVKey.INITIAL_LONGITUDE, 107.7139923);
					MainFrame frame = MainFrame.getInstance();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	private MainFrame() {
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent evt) {
				onWindowClosing(evt);
			}
		});
		setLookAndFill(UIManager.getSystemLookAndFeelClassName());
		annotLayer = new AnnotationLayer();
		listObject = new ArrayList<SurfaceObject>();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 525, 422);
		JPanel contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));

		wwd = new WorldWindowGLCanvas();
		contentPane.add(wwd, BorderLayout.CENTER);
		wwd.setModel(new BasicModel());
		//		wwd.getModel().getLayers().clear();
		wwd.getModel().getLayers().add(new MSVirtualEarthLayer());
		wwd.getModel().getLayers().add(getLintasanLayer());
		eastPanel = new EastPanel(this);
		contentPane.add(eastPanel, BorderLayout.EAST);
		southPanel = new SouthPanel(this);
		contentPane.add(southPanel, BorderLayout.SOUTH);

	}

	private void onWindowClosing(WindowEvent evt) {
		try {
			if(cas !=null){
				if(cas.getMyIdentity()!=null){
					if(cas.getMyIdentity().getKeretaApi()!=null){
						cas.getMyIdentity().getKeretaApi().setAvailable(true);
						DAOFactory.createKeretaApiDao().update(cas.getMyIdentity().getKeretaApi());	
					}
				}	
			}
			ResourceManager.close(DAOFactory.getInstance().getConnection());
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
		}
	}

	private void setLookAndFill(String className) {
		try {
			UIManager.setLookAndFeel(className);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
	}

	public static MainFrame getInstance(){
		if(thisFrame==null){
			thisFrame = new MainFrame();
		}
		return thisFrame;
	}
	public void setCas(CAS cas){
		this.cas = cas;
		cas.addObserver(this);
	}
	public CAS getCas(){
		return cas;
	}
	public EastPanel getEastPanel(){
		return eastPanel;
	}
	public WorldWindowGLCanvas getWwd(){
		return wwd;
	}
	public Thread getDisplayThread(){
		return displayThread;
	}
	public void setDisplayThread(Thread displayThread){
		this.displayThread = displayThread; 
	}
	public void setStarting(boolean starting){
		objectDisplayer.setStarting(starting);
	}
	public List<SurfaceObject> getListObject() {
		return listObject;
	}
	public ObjectDisplayer getObjectDisplayer(){
		return objectDisplayer;
	}
	public void setObjectDisplayer(ObjectDisplayer objectDisplayer){
		this.objectDisplayer = objectDisplayer;
		setDisplayThread(new Thread(this.objectDisplayer));
	}
	public AnnotationLayer getAnnotLayer(){
		return annotLayer;
	}
	public SouthPanel getSouthPanel(){
		return southPanel;
	}
	@Override
	public void update(Observable arg0, Object arg1) {
		for(int i = 0;i<cas.getAnotherTrains().size();i++){
			Identity train = cas.getAnotherTrains().get(i);
			boolean isAvailable = false;
			for(int j = 1; j < listObject.size()&&!isAvailable;j++){
				if(train.getKeretaApi().getIdKA().equals(listObject.get(j).id))
					isAvailable = true;
			}
			if(!isAvailable){
				listObject.add(new SurfaceObject(train.getKeretaApi().getIdKA(),
						train.getCurCoord().getLatitude().getDegrees(), 
						train.getCurCoord().getLongitude().getDegrees(), 
						Material.RED));
				objectDisplayer.getListAnnotations().add(new GlobeAnnotation(train.getKeretaApi().getIdKA()+"\n"+Float.valueOf(String.valueOf(train.getSpeed(true)*3600.0/1000.0))+"Km/h", train.getPosition(),objectDisplayer.getGeoAttr()));
				annotLayer.addAnnotation(objectDisplayer.getListAnnotations().get(objectDisplayer.getListAnnotations().size()-1));
				wwd.getModel().getLayers().add(listObject.get(listObject.size()-1));
				objectDisplayer.setUpdate(true);
			}
		}
		for(int i = 1;i<listObject.size();i++){
			SurfaceObject ob = listObject.get(i);
			boolean isAvailable = false;
			for(int j = 0;j<cas.getAnotherTrains().size();j++){
				if(ob.id.equals(cas.getAnotherTrains().get(j).getKeretaApi().getIdKA()))
					isAvailable = true;
			}
			if(!isAvailable){
				annotLayer.removeAnnotation(objectDisplayer.getListAnnotations().get(i));
				wwd.getModel().getLayers().remove(listObject.get(i));
				listObject.remove(ob);	
				objectDisplayer.setUpdate(true);
			}
		}
	}

	private Layer getLintasanLayer(){
		RenderableLayer layer = new RenderableLayer();
		layer.setName("Lintasan");
		try {
			RuteDao ruteDao = DAOFactory.createRuteDao();
			String[] namaRute = ruteDao.getListNamaRute();
			//			for (int i = 0; i < namaRute.length/2; i++) {
			System.out.println(namaRute[0]);
			List<RuteBean> rute = ruteDao.getRuteWhereNamaRute(namaRute[0]);
			List<Position> listPos = new ArrayList<Position>(rute.size());
			for (int j =0;j<rute.size();j++) {
				listPos.add(Position.fromDegrees(
						rute.get(j).getCoordinate().getLatitude().getDegrees(), 
						rute.get(j).getCoordinate().getLongitude().getDegrees()));
			}
			Polyline line = new Polyline(listPos);
			line.setColor(Color.white);
			line.setLineWidth(1);
			layer.addRenderable(line);
//						}
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(thisFrame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
		}
		return layer;
	}
}
